﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MOKA.TPM.Utility
{
    public class RandomStringUtils
    {
        private static Random RANDOM = new Random();

        public static String random(int count)
        {
            return random(count, false, false);
        }

        public static String randomAscii(int count)
        {

            return random(count, 32, 127, false, false);
        }

        public static String randomAlphabetic(int count)
        {
            return random(count, true, false);
        }

        public static String randomAlphanumeric(int count)
        {
            return random(count, true, true);


        }

        public static String randomNumeric(int count)
        {
            return random(count, false, true);
        }

        public static String random(int count, Boolean letters, Boolean numbers)
        {
            return random(count, 0, 0, letters, numbers);
        }

        public static String random(int count, int start, int end, Boolean letters, Boolean numbers)
        {
            return random(count, start, end, letters, numbers, null, RANDOM);
        }

        public static String random(int count, int start, int end, Boolean letters, Boolean numbers, char[] chars)
        {
            return random(count, start, end, letters, numbers, chars, RANDOM);
        }

        public static String random(int count, int start, int end, Boolean letters, Boolean numbers, char[] chars, Random random)
        {
            if (count == 0)
                return "";
            if (count < 0)
            {
                throw new Exception("Requested random string length " + count + " is less than 0.");
            }
            if ((chars != null) && (chars.Length == 0))
            {
                throw new Exception("The chars array must not be empty");
            }

            if ((start == 0) && (end == 0))
            {
                if (chars != null)
                {
                    end = chars.Length;
                }
                else if ((!letters) && (!numbers))
                {
                    end = 2147483647;
                }
                else
                {
                    end = 123;
                    start = 32;
                }

            }
            else if (end <= start)
            {
                throw new Exception("Parameter end (" + end + ") must be greater than start (" + start + ")");
            }

            char[] buffer = new char[count];
            int gap = end - start;

            while (count-- != 0)
            {
                char ch;
                if (chars == null)
                    ch = (char)(random.Next(gap) + start);
                else
                {
                    ch = chars[(random.Next(gap) + start)];
                }
                if (((letters) && (Char.IsLetter(ch))) || ((numbers) && (Char.IsLetter(ch))) || ((!letters) && (!numbers)))
                {
                    if ((ch >= 56320) && (ch <= 57343))
                    {
                        if (count == 0)
                        {
                            count++;
                        }
                        else
                        {
                            buffer[count] = ch;
                            count--;
                            buffer[count] = ((char)(55296 + random.Next(128)));
                        }
                    }
                    else if ((ch >= 55296) && (ch <= 56191))
                    {
                        if (count == 0)
                        {
                            count++;
                        }
                        else
                        {
                            buffer[count] = ((char)(56320 + random.Next(128)));
                            count--;
                            buffer[count] = ch;
                        }
                    }
                    else if ((ch >= 56192) && (ch <= 56319))
                    {
                        count++;
                    }
                    else buffer[count] = ch;
                }
                else
                {
                    count++;
                }
            }
            return new String(buffer);
        }

        public static String random(int count, String chars)
        {
            if (chars == null)
            {
                return random(count, 0, 0, false, false, null, RANDOM);
            }
            return random(count, chars.ToCharArray());
        }

        public static String random(int count, char[] chars)
        {
            if (chars == null)
            {
                return random(count, 0, 0, false, false, null, RANDOM);
            }
            return random(count, 0, chars.Length, false, false, chars, RANDOM);
        }
    }
}